/**
 * Copyright (c) 2009  Collaborative Development Group, C.S. Dept., University of Bari
 *
 * All rights reserved. This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License v1.0  which accompanies this distribution, and is 
 * available at http://www.eclipse.org/legal/epl-v10.html
 */
package it.uniba.di.cdg.jtalk.ui.login;

import static it.uniba.di.cdg.jtalk.ui.login.ILoginPresentationModel.AUTOMATIC_LOGIN_PROPERTY;
import static it.uniba.di.cdg.jtalk.ui.login.ILoginPresentationModel.PASSWORD_PROPERTY;
import static it.uniba.di.cdg.jtalk.ui.login.ILoginPresentationModel.REMEMBER_PASSWORD_PROPERTY;
import static it.uniba.di.cdg.jtalk.ui.login.ILoginPresentationModel.USER_ID_PROPERTY;
import static org.eclipse.jface.layout.GridDataFactory.fillDefaults;
import it.uniba.di.cdg.jtalk.core.IUserSession;
import it.uniba.di.cdg.penelope.ui.lnf.FormLookAndFeel;
import it.uniba.di.cdg.penelope.ui.lnf.IWidgetFactory;
import it.uniba.di.cdg.penelope.ui.mvp.ManagedViewPart;
import it.uniba.di.cdg.penelope.ui.mvp.PresenterEvent;
import it.uniba.di.cdg.penelope.ui.mvp.databinding.DataBind;
import it.uniba.di.cdg.penelope.ui.swt.SWTAsyncExec;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * The contact view is a special view: it acts as 
 * <ul>
 * <li>a login screen (for the user to insert username/password), if {@link IUserSession#isLoggedIn()} returns <code>false</code>;</li>
 * <li>a contacts management list, if {@link IUserSession#isLoggedIn()} returns <code>true</code>.</li>
 * </ul>
 */
@Singleton
public class LoginView extends ManagedViewPart implements ILoginView {

	private final IWidgetFactory widgetFactory;

	// TODO Factor this into the widget factory
	private FormToolkit toolkit;
	
	
	// Fields
	@DataBind( USER_ID_PROPERTY )
	private Text txtUserId;
	@DataBind( PASSWORD_PROPERTY )
	private Text txtPassword;
	// Options
	@DataBind( REMEMBER_PASSWORD_PROPERTY )
	private Button checkRememberPassword; 
	@DataBind( AUTOMATIC_LOGIN_PROPERTY )
	private Button checkAutomaticLogin;

	@PresenterEvent( LogInButtonClicked.class )
	private Button loginButton;
	
	@Inject
	public LoginView( @FormLookAndFeel IWidgetFactory widgetFactory ) {
		this.widgetFactory = widgetFactory;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override @PostConstruct
	public void createPartControl( Composite parent ) {
		parent.setLayout( new FillLayout( SWT.VERTICAL ) );
		
		toolkit = new FormToolkit( Display.getCurrent() );
		Form form = (Form) widgetFactory.newForm( parent );
		form.setText( "Login" );

		GridLayout layout = new GridLayout( 1, true );
		form.getBody().setLayout( layout );
		
		Composite composite = toolkit.createComposite( form.getBody(), SWT.NONE );
		txtUserId = newTextField( composite, "UserId", "" );
		fillDefaults().align( SWT.FILL, SWT.BEGINNING ).applyTo( txtUserId );
		txtPassword = newTextField( composite, "Password", "", SWT.PASSWORD );
		fillDefaults().align( SWT.FILL, SWT.BEGINNING ).applyTo( txtPassword );

		GridLayout accountLayout = new GridLayout( 1, true );
		accountLayout.marginTop = 60;
		accountLayout.marginLeft = 40;
		accountLayout.marginRight = 40;
		composite.setLayout( accountLayout );
		fillDefaults()
			.grab( true, false )
			.align( SWT.FILL, SWT.BEGINNING ).hint( SWT.DEFAULT, SWT.DEFAULT ).span( SWT.DEFAULT, 20 )
			.applyTo( composite );		
		
		loginButton = toolkit.createButton( form.getBody(), "Login", SWT.NONE );
		fillDefaults()
			.align( SWT.CENTER, SWT.CENTER ).hint( 100, SWT.DEFAULT ).span( SWT.DEFAULT, 20 )
			.applyTo( loginButton );		
		createOptionsSection( form );	
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.swt.widgets.Composite#setFocus()
	 */
	@Override
	public void setFocus() {
		// TODO Manage focus for errors
		this.txtUserId.setFocus();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.swt.widgets.Widget#dispose()
	 */
	@Override @PreDestroy
	public void dispose() {
		toolkit.dispose();
		super.dispose();
	}

	/* (non-Javadoc)
	 * @see it.uniba.di.cdg.jtalk.ui.login.ILoginView#enableUserInput(boolean)
	 */
	@Override @SWTAsyncExec
	public void enableUserInput( boolean enable ) {
		System.out.println( String.format( "LoginView.enableUserInput( %s )", enable ) );
		txtUserId.setEnabled( enable );
		txtPassword.setEnabled( enable );
		
		
//		getSite().getShell().setEnabled( enable );
	}	

	/* (non-Javadoc)
	 * @see it.uniba.di.cdg.jtalk.ui.login.ILoginView#showErrorMessage(java.lang.String)
	 */
	@Override @SWTAsyncExec
	public void showError( String errorMessage ) {
		System.out.println( String.format( "LoginView.showErrorMessage( %s )", errorMessage ) );
		MessageDialog.openError( getSite().getShell(), "Error", errorMessage );
		txtUserId.setFocus();
	}
	
	/**
	 * @param composite
	 */
	private void createOptionsSection( final Form form ) {
		Composite composite = form.getBody();
		Section section = toolkit.createSection( composite, 
				Section.DESCRIPTION | Section.TITLE_BAR | Section.TWISTIE
				| Section.EXPANDED | SWT.FILL | Section.CLIENT_INDENT | Section.FOCUS_TITLE );
		fillDefaults()
			.align( SWT.FILL, SWT.BEGINNING ).span( SWT.DEFAULT, 20 )
			.applyTo( section );		

		section.setText( "Options" );
		section.setDescription( "Settings to be applied" );
		Composite sectionClient = toolkit.createComposite( section );
		sectionClient.setLayout( new GridLayout() );
		section.setClient( sectionClient );
		
		checkRememberPassword = toolkit
			.createButton( sectionClient, "Remember password", SWT.CHECK );
		checkRememberPassword.setToolTipText( "The account form will be automatically filled next time you start the application" );
		checkAutomaticLogin = toolkit
				.createButton( sectionClient, "Perform automatic login at startup", SWT.CHECK );
		checkAutomaticLogin.setToolTipText( "If the account crendetials have been save, next time you will be automatically logged in" );
	}

	/* (non-Javadoc)
	 * @see it.uniba.di.cdg.jtalk.ui.login.ILoginView#enableLoginButton(boolean)
	 */
	@Override @SWTAsyncExec
	public void enableLoginButton( boolean enable ) {
		this.loginButton.setEnabled( enable );
	}
	
	// XXX Abstract this
	
	protected Text newTextField( Composite composite, String label, String initialValue ) {
		return newTextField( composite, label, initialValue, SWT.NONE );
	}

	protected Text newTextField( Composite composite, String labelText, String initialValue, int swtFlags ) {
		GridData gridData = null;
		Label label = toolkit.createLabel( composite, labelText );
		gridData = new GridData( SWT.FILL, SWT.FILL, true, false );
		gridData.widthHint = SWT.DEFAULT;
		gridData.heightHint = SWT.DEFAULT;
		label.setLayoutData( gridData );

		Text txtControl = toolkit.createText( composite, initialValue, swtFlags );
		gridData = new GridData( SWT.FILL, SWT.FILL, true, false );
		gridData.widthHint = SWT.DEFAULT;
		gridData.heightHint = SWT.DEFAULT;
		txtControl.setLayoutData( gridData );
		
		return txtControl;
	}
}